

/***************************************************
FRAME_TAIL_MODE_1:
	frame_header: 	0xAA
	"frame_tail can not as the same as frame_header !"
	frame_tail: 	0x55								//no palyload_len !
	"palyload can't appear the same data as frame_tail"
	palyload: 		0x55 -> 0XAA;						//frame_tail change
					0XAA -> 0xAA 0XAA;
					...
	e.g.
	 0x01 0xAA 0XAA 0XAA 0x02 ->
	 0x01 0xAA      0X55 0x02 ->

*****************************************************
FRAME_TAIL_MODE_2:
	escape_character: 0xFF
	frame_header: 	0xAA
	"frame_tail can not as the same as frame_header !"
	frame_tail: 	0x55								//no palyload_len !
	"palyload can't appear the same data as frame_tail"
	palyload: 		0x55 -> 0xFF;						//frame_tail change
					0xFF -> 0xFF 0xFF;					//escape_character change
					0xFF 0xFF -> 0xFF 0xFF 0xFF 0xFF;
					...
	e.g.
	 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0x02 ->
	 0x01 0xFF      0xFF      0x55 0x02

*****************************************************
PALYLOAD_LEN_MODE_1:
	escape_character: 0xFF
	frame_header: 	0xAA
	"palyload can't appear the same data as frame_header"
	palyload: 		0xAA -> 0xFF;						//frame_header change
					0xFF -> 0xFF 0xFF;					//escape_character change
					0xFF 0xFF -> 0xFF 0xFF 0xFF 0xFF;
					...
	e.g.
	 0x01 0xFF 0xFF 0xFF 0xFF 0xFF 0x02 ->
	 0x01 0xFF      0xFF      0xAA 0x02
*****************************************************
"if the frame_header or frame_tail was not a single char, \
we can't make sure the palyload not appear the same data as frame_header or frame_tail"
***************************************************/

#include "../../lib/type.h"

#include <frame_recive_config.h>
#include <string.h>

static const uint8_t frame_header[] = FRAME_HEADER;
static uint8_t frame_start_check_count = 0;
uint8_t frame_recive_start_check(uint8_t rec_byte)
{
	if(frame_header[frame_start_check_count] == rec_byte){
		frame_start_check_count++;
		if(frame_start_check_count == sizeof(frame_header)){
			frame_start_check_count = 0;
			return 1;
		}
	}
	else{
		frame_start_check_count = 0;
	}
	return 0;
}

void frame_recive_start_check_init(void)
{
	frame_start_check_count = 0;
}

void frame_recive_get_frame_head(uint8_t* frame_head, uint8_t* frame_head_len)      //copy the frame head to *frame_head, and return frame_head_len
{
    memcpy(frame_head, frame_header, sizeof(frame_header));
    *frame_head_len = sizeof(frame_header);
}

/***************************************************/
#if (FRAME_FINISH_CHECK_BY == FRAME_FINISH_CHECK_BY_LEN)
static uint8_t frame_finish_check_frame_len = 0;
uint8_t frame_recive_finish_check(uint8_t rec_byte)
{
	if(rec_byte == 0){
		return 1;
	}

	if(frame_finish_check_frame_len == 0){
		frame_finish_check_frame_len = rec_byte;
	}
	else{
		frame_finish_check_frame_len--;
		if(frame_finish_check_frame_len == 0){
			return 1;
		}
	}

	return 0;
}

void frame_recive_finish_check_init(void)
{
	frame_finish_check_frame_len = 0;
}
#endif

#if (FRAME_FINISH_CHECK_BY == FRAME_FINISH_CHECK_BY_TAIL)
static const uint8_t frame_tail[] = FRAME_TAIL;
static uint8_t frame_finish_check_count = 0;
uint8_t frame_recive_finish_check(uint8_t rec_byte)
{
	if(frame_tail[frame_finish_check_count] == rec_byte){
		frame_finish_check_count++;
		if(frame_finish_check_count == sizeof(frame_tail)){
			frame_finish_check_count = 0;
			return 1;
		}
	}
	else{
		frame_finish_check_count = 0;
	}
	return 0;
}

void frame_recive_finish_check_init(void)
{
	if(sizeof(frame_header) == sizeof(frame_tail)){
		if(memcmp(frame_tail, frame_header, sizeof(frame_tail)) == 0){
//			printf("frame_tail can not as the same as frame_header !");
			while(1);
		}
	}
	frame_finish_check_count = 0;
}
#endif


#include "frame_recive_public.h"
void frame_recive_std_init(void)
{
  	frame_recive_start_check_callback_reg(frame_recive_start_check);
	frame_recive_start_check_init_callback_reg(frame_recive_start_check_init);
	frame_recive_get_frame_head_callback_reg(frame_recive_get_frame_head);
	frame_recive_finish_check_callback_reg(frame_recive_finish_check);
	frame_recive_finish_check_init_callback_reg(frame_recive_finish_check_init);
	frame_recive_init();
}